package yuchen.androidocr.imageUtil;

import java.util.ArrayList;

/**
 * Created by yuchen on 16/5/10.
 */
public class dataSet {


    ArrayList data = new ArrayList();
    private int length = 0;
    private int areaWidth = 0;
    private int areaHeight = 0;



    private int width;
    private int height;
    private ArrayList area = new ArrayList();
    private ArrayList record = new ArrayList();
    private boolean isnoise = false;

    public dataSet(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public void flush() {
        this.length = this.data.size();
        int len = this.length;
        this.area = new ArrayList();
        this.record = new ArrayList();
        this.areaHeight = 0;
        this.areaWidth = 0;
        int i;
        int[] pot;
        int x, y;
        if (this.length == 0) {
            return;
        }
        pot = (int[])this.data.get(0);
        int maxW = pot[0], minW = pot[0], maxH = pot[1], minH = pot[1];
        int[] maxWs = pot, minWs = pot, maxHs = pot, minHs = pot;
        int maxWs_s = -1,minWs_s = -1,maxHs_s = -1,minHs_s = -1;
        for (i = 1; i < len; i++) {
            pot = (int[])this.data.get(i);
            x = pot[0];
            y = pot[1];
            if (x > maxW) {
                maxW = x;
                maxWs_s = i;
            } else if (x < minW) {
                minW = x;
                minWs_s = i;
            }
            if (y > maxH) {
                maxH = y;
                maxHs_s = i;
            } else if (y < minH) {
                minH = y;
                minHs_s = i;
            }
        }
        this.areaHeight = maxH - minH + 1;
        this.areaWidth = maxW - minW + 1;
        this.area.add(minW);
        this.area.add(maxW);
        this.area.add(minH);
        this.area.add(maxH);
        addListOrNum(maxWs, maxWs_s, this.record);
        addListOrNum(minWs, minWs_s, this.record);
        addListOrNum(maxHs, maxHs_s, this.record);
        addListOrNum(minWs, minWs_s, this.record);

        this.check();
    }

    public void addListOrNum(int[] arr, int checkNum,ArrayList list) {
        if (checkNum != -1) {
            list.add(checkNum);
        }else{
            list.add(arr);
        }
    }

    public void check() {
        int[] xcol = new int[this.width];
        int[] ycol = new int[this.height];
        int i, x, y;
        int[] pot = new int[2];
        for (i = 0; i < xcol.length; i++) {
            xcol[i] = 0;
        }
        for (i = 0; i < ycol.length; i++) {
            ycol[i] = 0;
        }
        int len = this.data.size();
        for (i = 0; i < len; i++) {
            pot = (int[])this.data.get(i);
            x = pot[0];
            y = pot[1];
            xcol[x]++;
            ycol[y]++;
        }

        int thx = width * 90 / 100;
        int thy = height * 90 / 100;
        for (i = 0; i < xcol.length; i++) {
            if (xcol[i] >= thx) {
                this.isnoise = true;
                return;
            }
        }
        for (i = 0; i < ycol.length; i++) {
            if (ycol[i] >= thy) {
                this.isnoise = true;
                return;
            }
        }
    }

    public int counthorizontal(int y,int startX,int endX){
        int calRowsNum = 0;
        int i;
        int[] pot;
        for (i = 0; i < this.length; i++) {
            pot = (int[])this.data.get(i);
            if (pot[1] == y && (pot[0] <= endX) && (pot[0] >= startX)) {
                calRowsNum++;
            }
        }
        return calRowsNum;
    };

    public String recoNum (ArrayList digialArea){
        double y0, numHeight, x0, numWidth;
        y0 = (int)this.area.get(2) * 1.00000;
        x0 = (int)this.area.get(0) * 1.00000;
        numHeight = this.areaHeight;
        numWidth = this.areaWidth;
        /* ---------------------------七段识别-------------------------------------------------
         高度（行）分三段，竖分两段  x0记录横的起始位置，
         * */
        String resultNum = "";
        //七段码一段的长度
        double heightY0 = y0;
        double heightY1 = Math.floor(y0 + numHeight / 3);
        double heightY2 = Math.floor(y0 + numHeight / 3 * 2);
        double heightY3 = Math.floor(y0 + numHeight);

        double r = numHeight / numWidth;
        int minH = (int)digialArea.get(2), maxH = (int)digialArea.get(3);
        if (this.areaHeight<(maxH-minH+1)/2) {
            /*最大像素值大于一个段宽区分小数点和1*/
            if(y0>(minH+maxH)/2){
                resultNum = ".";
            }
        } else if (r > 4) {
            resultNum = "1";
        } else {
            //数字识别串
            String restultStr = "";
            double constantX = Math.floor(x0 + 0.5 * numWidth); //常量，for控制
            //A值
            restultStr += this.judgeZeroOrOneX(constantX, heightY0, heightY1);
            //B值
            restultStr += this.judgeZeroOrOneX(constantX, heightY1, heightY2);
            //c值
            restultStr += this.judgeZeroOrOneX(constantX, heightY2, heightY3);
            //D、E都是heightY1的纵坐标，F、G是heightY2纵坐标

            double startX1 = Math.floor(x0 + 0.5 * numWidth);
            double startX2 = Math.floor((int)x0 + (int)numWidth);
            //D值
            restultStr += this.judgeZeroOrOneY(heightY1, x0, startX1);
            //E值
            restultStr += this.judgeZeroOrOneY(heightY1, startX1, startX2);
            //F值
            restultStr += this.judgeZeroOrOneY(heightY2, x0, startX1);
            //G值
            restultStr += this.judgeZeroOrOneY(heightY2, startX1, startX2);
            //alert(restultStr);
            resultNum = this.resultRecognition(restultStr);
        }
        return resultNum;
    };

    public String judgeZeroOrOneX(double x, double startY, double endY){
        int calCloumnNum = 0;
        int i;
        int[] pot;
        for (i = 0; i < this.length; i++) {
            pot = (int[])this.data.get(i);
            if (pot[0] == x && (pot[1] <= endY) && (pot[1] >= startY)) {
                calCloumnNum++;
            }
        }

        if (calCloumnNum > 1) {
            return "1";
        } else {
            return "0";
        }
    };
    // 查看水平位置
    public int counthorizontal(double y,double startX,double endX){
        int calRowsNum = 0;
        int i;
        int[] pot;
        for (i = 0; i < this.length; i++) {
            pot = (int[])this.data.get(i);
            if (pot[1] == y && (pot[0] <= endX) && (pot[0] >= startX)) {
                calRowsNum++;
            }
        }
        return calRowsNum;
    };

    public String judgeZeroOrOneY(double y,double startX,double endX){

        int calRowsNum = 0;
        int i;
        int pot[];
        for (i = 0; i < this.length; i++) {
            pot = (int[])this.data.get(i);
            if (pot[1] == y && (pot[0] <= endX) && (pot[0] >= startX)) {
                calRowsNum++;
            }
        }
        //alert(calCloumnNum);
        if (calRowsNum > 1) {
            return "1";
        } else {
            return "0";
        }
    };

    public String resultRecognition(String recognitionNum){
        String returnNum;
        //2,5不在此处理
        switch (recognitionNum) {
            //0
            case "1011111":
                returnNum = "0";
                break;
            //1
            case "0000101":
                returnNum = "1";
                break;
            //2
            case "1110110":
                returnNum = "2";
                break;
            //3
            case "1110101":
                returnNum = "3";
                break;
            //4
            case "0101101":
                returnNum = "4";
                break;
            //5
            case "1111001":
                returnNum = "5";
                break;
            //6
            case "1111011":
                returnNum = "6";
                break;
            //7
            case "1000101":
                returnNum = "7";
                break;
            case "1001101":
                returnNum = "7";
                break;
            //8
            case "1111111":
                returnNum = "8";
                break;
            //9
            case "1111101":
                returnNum = "9";
                break;
            default:
                returnNum = "NaN"; //无法识别
        }
        return returnNum;
    }

    public ArrayList getData() {
        return data;
    }

    public int getLength() {
        return length;
    }

    public int getAreaWidth() {
        return areaWidth;
    }

    public int getAreaHeight() {
        return areaHeight;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public ArrayList getArea() {
        return area;
    }

    public ArrayList getRecord() {
        return record;
    }

    public boolean isnoise() {
        return isnoise;
    }
}
